#include "delay.h"
#include "printf.h"
#include <stdbool.h>
#include <stdio.h>
#include <stm32f10x.h>

void LED_init() {

    GPIO_InitTypeDef def;
    def.GPIO_Mode = GPIO_Mode_Out_PP;
    def.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
    def.GPIO_Speed = GPIO_Speed_50MHz;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
    //要开启 复用 RCC_APB2Periph_AFIO 才能禁用 PB3,PB4的先被占用的引脚功能
    // JTDO/TRACESWO PB3
    // JNTRST PB4
    // PB3,PB4 程序还没开始就已经被占用了，需要设置恢复它的IO功能！！！
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
    GPIO_Init(GPIOB, &def);
    // B3 必须为 0 ，也就是 - ，上面虽然是一个 -，但是它狗日的是一个接地，
    //否则无法亮灯。“-”代表接地！！！
    GPIO_Write(GPIOB, ~0x78);
}

void LED_on_or_off() {
    static bool on = true;
    unsigned short r = GPIO_ReadInputData(GPIOB);
    // printf("GPIOB: %#X\r\n", r = GPIO_ReadInputData(GPIOB));
    // GPIO_Write(GPIOB, r | 0x40);

    // GPIO_WriteBit(GPIOB, GPIO_Pin_4, Bit_SET);

    if (on) {
        GPIO_Write(GPIOB, r | 0x70);
    } else {
        GPIO_Write(GPIOB, r & ~0x78);
    }
    on = !on;
}

void light_sensor_init() {

    // A0 VCC A1 GND A2 DO A3 AO
    // A2 used to EXTI interrupt
    GPIO_InitTypeDef def;
    def.GPIO_Mode = GPIO_Mode_Out_PP;
    def.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
    def.GPIO_Speed = GPIO_Speed_50MHz;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_Init(GPIOA, &def);

    // AO set to input,otherwise A3 0 forever
    // A2 must set input mode
    def.GPIO_Mode = GPIO_Mode_IPU;
    def.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_2;
    GPIO_Init(GPIOA, &def);

    // GPIO_Write(GPIOA,-1 <<4|1);
    GPIO_Write(GPIOA, ~0xE);
}

void EXTI2_init() {

    EXTI_InitTypeDef EXTI_Initial;
    NVIC_InitTypeDef NVIC_Initial;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource2);

    EXTI_Initial.EXTI_Line = EXTI_Line2;
    EXTI_Initial.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_Initial.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_Initial.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_Initial);

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    NVIC_Initial.NVIC_IRQChannel = EXTI2_IRQn;
    NVIC_Initial.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_Initial.NVIC_IRQChannelSubPriority = 2;
    NVIC_Initial.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_Initial);
}

void EXTI2_IRQHandler() {
    // printf("interrupt status: %d\r\n", EXTI_GetITStatus(EXTI_Line2));
    if (EXTI_GetITStatus(EXTI_Line2) == SET) {
        printf("GPIOA interrupt: %#X\r\n", GPIO_ReadInputData(GPIOA));
        LED_on_or_off();
        EXTI_ClearITPendingBit(EXTI_Line2);
    }
}

int main() {

    /*
    1.RGB等下面引脚"-"表示接地，必须为IO引脚为0，否则不亮
    2. PB3,PB4引脚已经被占用了，必须禁用单片机一开始的占用状态，
    也就是如下复用功能
    JTDO/TRACESWO PB3
        JNTRST PB4
    3.禁用复用功能必须开启 AFIO，然后禁用相应功能（修改复用IO的寄存器）
    */
    printf_init(9600);
    delay_init();
    light_sensor_init();
    EXTI2_init();
    LED_init();

    while (true) {

        printf("GPIOA: %#X\r\n", GPIO_ReadInputData(GPIOA));
        printf("GPIOB: %#X\r\n", GPIO_ReadInputData(GPIOB));

        delay_s(3);
    }

    return 0;
}
